﻿using OpenTK.Graphics.OpenGL;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace testopenTk
{
    public static class MyInfo
    {
        public static EventWaitHandle context_ready = new EventWaitHandle(false, EventResetMode.AutoReset);
        public static List<AssLoad> alList = new List<AssLoad>();

        public static void Save(List<Sprite3D> sl)
        {
            using (FileStream fs = new FileStream("model.info", FileMode.OpenOrCreate, FileAccess.ReadWrite))
            {
                using (BinaryWriter bw = new BinaryWriter(fs, Encoding.Unicode))
                {
                    bw.Write((Int32)sl.Count);//模型数量
                    foreach (Sprite3D t in sl)
                    {
                        bw.Write(t.spath);
                        bw.Write(t.si.Location_X.Value);
                        bw.Write(t.si.Location_Y.Value);
                        bw.Write(t.si.Location_Z.Value);
                        bw.Write(t.si.Rotate_X.Value);
                        bw.Write(t.si.Rotate_Y.Value);
                        bw.Write(t.si.Rotate_Z.Value);
                    }
                }
            }
        }

        public static void Read()
        {
            SpriteList.DisposeResoure();
            using (FileStream fs = new FileStream("model.info", FileMode.OpenOrCreate, FileAccess.ReadWrite))
            {
                using (BinaryReader br = new BinaryReader(fs, Encoding.Unicode))
                {
                    int count = br.ReadInt32();
                    for (int i = 0; i < count; i++)
                    {
                        Sprite3D t = new Sprite3D(br.ReadString());
                        t.si.Location_X.Value += br.ReadDecimal();
                        t.si.Location_Y.Value += br.ReadDecimal();
                        t.si.Location_Z.Value += br.ReadDecimal();
                        t.si.Rotate_X.Value += br.ReadDecimal();
                        t.si.Rotate_Y.Value += br.ReadDecimal();
                        t.si.Rotate_Z.Value += br.ReadDecimal();
                        t.touch = false;
                        SpriteList.sprite3Dlist.Add(t);
                    }
                }
            }
        }

        public static void AssSave(List<Sprite3D> sl)
        {

            using (FileStream fs = new FileStream("Assmodel.info", FileMode.Create, FileAccess.ReadWrite))
            {
                using (BinaryWriter bw = new BinaryWriter(fs, Encoding.Unicode))
                {
                    bw.Write(sl.Count);
                    foreach (Sprite3D t in sl)
                    {
                        string[] sTemp = t.spath.Split('/', '\\');
                        bw.Write("Res/"+sTemp[sTemp.Length-1]);
                        bw.Write(t.AssDraw.MeshIndex);
                        bw.Write(t.si.num_Animation.Value);
                        bw.Write(t.si.Location_X.Value);
                        bw.Write(t.si.Location_Y.Value);
                        bw.Write(t.si.Location_Z.Value);
                        bw.Write(t.si.Rotate_X.Value);
                        bw.Write(t.si.Rotate_Y.Value);
                        bw.Write(t.si.Rotate_Z.Value);
                        bw.Write(t.si.num_layer.Value);
                    }
                }
            }
        }

        public static void AssRead()
        {
            #region readFile
            SpriteList.DisposeResoure();

            using (FileStream fs = new FileStream("Assmodel.info", FileMode.OpenOrCreate, FileAccess.ReadWrite))
            {
                using (BinaryReader br = new BinaryReader(fs, Encoding.Unicode))
                {

                    int count = br.ReadInt32();
                    for (int i = 0; i < count; i++)
                    {
                        string FilePath = br.ReadString();
                        int meshindex = br.ReadInt32();
                        bool created = false;
                        foreach (var s in alList)
                        {
                            if (s.filePath == FilePath)
                            {
                                created = true;
                            }
                        }
                        if (!created)
                        {
                            alList.Add(new AssLoad(FilePath));
                        }
                        try
                        {
                            foreach (AssLoad tempList in alList)
                            {
                                if (FilePath == tempList.filePath)
                                {
                                    foreach (DrawInfo di in tempList.DrawInfoList)
                                    {
                                        if (di.MeshIndex == meshindex)
                                        {
                                            Sprite3D t = new Sprite3D(FilePath, di);
                                            t.si.num_Animation.Value = br.ReadDecimal();
                                            t.si.Location_X.Value = br.ReadDecimal();
                                            t.si.Location_Y.Value = br.ReadDecimal();
                                            t.si.Location_Z.Value = br.ReadDecimal();
                                            t.si.Rotate_X.Value = br.ReadDecimal();
                                            t.si.Rotate_Y.Value = br.ReadDecimal();
                                            t.si.Rotate_Z.Value = br.ReadDecimal();
                                            t.si.num_layer.Value = br.ReadDecimal();
                                            t.touch = false;
                                            SpriteList.sprite3Dlist.Add(t);

                                        }
                                    }

                                }
                            }
                        }
                        catch
                        {
                            return;
                        }

                    }

                }
            }
            #endregion
        }

        static void AllLoad(string[] FilePath)
        {
            foreach (string t in FilePath)
            {
                OneLoad(t);
            }
        }
        /// <summary>
        /// 加载未加载的模型，若已加载则直接使用，并创建精灵
        /// </summary>
        /// <param name="f">文件路径</param>
        public static void OneLoad(string f)
        {
            bool created = false;
            foreach (AssLoad s in alList)
            {
                if (s.filePath == f)
                {
                    created = true;
                }
            }
            if (!created)
            {
                alList.Add(new AssLoad(f));
            }
            foreach (AssLoad tempAss in alList)
            {
                //查找出未创建的那个，待改进
                if (f == tempAss.filePath)
                {
                    foreach (DrawInfo di in tempAss.DrawInfoList)
                    {
                        SpriteList.sprite3Dlist.Add(new Sprite3D(f, di));
                    }

                }
            }
        }

        static List<ReadInfo> ReadInfoList = new List<ReadInfo>();

        /// <summary>
        /// 读取model.info的全部信息，并添加进ReadInfoList,
        /// 每个ReadInfo代表一个精灵
        /// </summary>
        public static void NewRead()
        {
            SpriteList.DisposeResoure();

            using (FileStream fs = new FileStream("Assmodel.info", FileMode.OpenOrCreate, FileAccess.Read))
            {
                using (BinaryReader br = new BinaryReader(fs, Encoding.Unicode))
                {
                    int count = br.ReadInt32();
                    for (int i = 0; i < count; i++)
                    {
                        ReadInfoList.Add(new ReadInfo(br.ReadString(),
                           br.ReadInt32(), br.ReadDecimal(), br.ReadDecimal(), br.ReadDecimal(),
                           br.ReadDecimal(), br.ReadDecimal(), br.ReadDecimal()));
                    }
                }
            }
            foreach (ReadInfo Ri in ReadInfoList)
            {
                bool created = false;
                foreach (AssLoad AL in alList)
                {
                    if (AL.filePath == Ri.FilePath)
                    {
                        created = true;
                    }
                }
                if (!created)
                {
                    foreach (AssLoad AL in alList)
                    {
                        if (AL.filePath == Ri.FilePath)
                        {
                            created = true;
                        }
                    }
                    alList.Add(new AssLoad(Ri.FilePath));
                }
                
            }
        }



        public static void printToTexture(int texture, string s)
        {
            Bitmap bm = new Bitmap(s.Length * 20, 20);
            GL.ActiveTexture(TextureUnit.Texture0);
            int temp=GL.GenTexture();
            GL.BindTexture(TextureTarget.Texture2D, temp);
            GL.Enable(EnableCap.Texture2D);
            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)All.Linear);
            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)All.Linear);
            GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, bm.Width, bm.Height, 0,
                OpenTK.Graphics.OpenGL.PixelFormat.Bgra, PixelType.UnsignedByte, IntPtr.Zero);
            foreach (var t in FontFamily.Families)
            {
                MyMessage.listbox(t.GetName(0));
            }
            Font drawFont = new Font("Arial", 16);
            SolidBrush br = new SolidBrush(Color.Black);
            using (Graphics gfx = Graphics.FromImage(bm))
            {
                gfx.Clear(Color.Transparent);
                gfx.DrawString(s, drawFont, br, 0, 0); // Draw as many strings as you need
            }
            BitmapData data = bm.LockBits(new Rectangle(0, 0, bm.Width, bm.Height), ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb);

            GL.ActiveTexture(TextureUnit.Texture1);
            GL.Enable(EnableCap.Texture2D);
            GL.BindTexture(TextureTarget.Texture2D, texture);
            GL.TexEnv(TextureEnvTarget.TextureEnv, TextureEnvParameter.TextureEnvMode, Color.Transparent);
            //GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, bm.Width, bm.Height, 0,
            //    OpenTK.Graphics.OpenGL.PixelFormat.Bgra, PixelType.UnsignedByte, data.Scan0);
            bm.UnlockBits(data);
            bm.Dispose();
            GL.ActiveTexture(TextureUnit.Texture0);
            GL.Enable(EnableCap.Texture2D);
        }
    }
}


